/* eslint-disable no-useless-escape */
/* eslint-disable camelcase */

const numberReg = /^-?[1-9][0-9]?.?[0-9]*$/
const intReg = /^-?[1-9][0-9]*$/
const phoneReg = /^1(3|4|5|6|7|8|9)\d{9}$/
const telephoneReg = /^(([0\+]\d{2,3}-)?(0\d{2,3})-)(\d{7,8})(-(\d{3,}))?$/
const emailReg = /^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/
const pwdReg = /^.{6,16}$/
const inviteCodeReg = /^[a-zA-Z0-9]{6,16}$/
const ip4Reg = /^([0-9]|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.([0-9]|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.([0-9]|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.([0-9]|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])$/
export default {
  isNull: function (val) {
    if (val === null || val === '' || val === 'undefined') {
      return true
    }
  },
  isNumber: function (val) {
    return numberReg.test(val)
  },
  isInt: function (val) {
    return intReg.test(val)
  },
  isPhone: function (val) {
    return phoneReg.test(val)
  },
  /**
	  * @description 判断数据是否为座机号(固定电话)
	  * @param {String} str_data 待校验的数据
	  * @returns {Boolean}, true:是座机号
	  **/
  isTelephone: function (val) {
    return telephoneReg.test(val)
  },
  isEmail: function (val) {
    return emailReg.test(val)
  },
  isPwd: function (val) {
    return pwdReg.test(val)
  },
  isInviteCode: function (val) {
    return inviteCodeReg.test(val)
  },
  checkCode: function (val) {
    const p = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
    var factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
    var parity = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2]
    var code = val.substring(17)
    if (p.test(val)) {
      var sum = 0
      for (var i = 0; i < 17; i++) {
        sum += val[i] * factor[i]
      }
      const newCode = parity[sum % 11] + ''
      if (newCode === code.toUpperCase()) {
        return true
      }
    }
    return false
  },
  checkDate: function (val) {
    const pattern = /^(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)$/
    if (pattern.test(val)) {
      const year = val.substring(0, 4)
      const month = val.substring(4, 6)
      const date = val.substring(6, 8)
      const date2 = new Date(year + '-' + month + '-' + date)
      if (date2 && date2.getMonth() === (parseInt(month) - 1)) {
        return true
      }
    }
    return false
  },
  checkProv: function (val) {
    var pattern = /^[1-9][0-9]/
    var provs = { 11: '北京', 12: '天津', 13: '河北', 14: '山西', 15: '内蒙古', 21: '辽宁', 22: '吉林', 23: '黑龙江 ', 31: '上海', 32: '江苏', 33: '浙江', 34: '安徽', 35: '福建', 36: '江西', 37: '山东', 41: '河南', 42: '湖北 ', 43: '湖南', 44: '广东', 45: '广西', 46: '海南', 50: '重庆', 51: '四川', 52: '贵州', 53: '云南', 54: '西藏 ', 61: '陕西', 62: '甘肃', 63: '青海', 64: '宁夏', 65: '新疆', 71: '台湾', 81: '香港', 82: '澳门' }
    if (pattern.test(val)) {
      if (provs[val]) {
        return true
      }
    }
    return false
  },
  /**
	 * 校验身份证
	 * **/
  isIdcard: function (val) {
    if (this.checkCode(val)) {
      var date = val.substring(6, 14)
      if (this.checkDate(date)) {
        if (this.checkProv(val.substring(0, 2))) {
          return true
        }
      }
    }
    return false
  },
  /**
	* @description 判断是否为统一社会信用代码
	* @param {String} str_data 待校验的数据
	* @returns {Boolean}, true:社会信用代码正确
	**/
  isCreditCode: function (str_data) {
    var patrn = /^[0-9A-Z]+$/
    // 18位校验及大写校验
    if ((str_data.length !== 18) || (patrn.test(str_data) === false)) {
      return false
    } else {
      var Ancode // 统一社会信用代码的每一个值
      var Ancodevalue // 统一社会信用代码每一个值的权重
      var total = 0
      var weightedfactors = [1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28] // 加权因子
      var str = '0123456789ABCDEFGHJKLMNPQRTUWXY'
      // 不用I、O、S、V、Z
      for (var i = 0; i < str_data.length - 1; i++) {
        Ancode = str_data.substring(i, i + 1)
        Ancodevalue = str.indexOf(Ancode)
        total = total + Ancodevalue * weightedfactors[i]
        // 权重与加权因子相乘之和
      }
      var logiccheckcode = 31 - total % 31
      if (logiccheckcode === 31) {
        logiccheckcode = 0
      }
      var Str = '0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,T,U,W,X,Y'
      var Array_Str = Str.split(',')
      logiccheckcode = Array_Str[logiccheckcode]
      var checkcode = str_data.substring(17, 18)
      if (logiccheckcode !== checkcode) {
        return false
      }
      return true
    }
  },
  /**
	* @description 判断是否为银行卡号
	* @param {String} str_cardNo 待校验的数据
	* @returns {Boolean}, true:是银行卡号
	**/
  isBankCard: function (str_cardNo) {
    str_cardNo = str_cardNo || String(this)
    if (str_cardNo.trim() === '' || undefined === str_cardNo) {
      return false
    }
    var lastNum = str_cardNo.substr(str_cardNo.length - 1, 1) // 取出最后一位（与luhm进行比较）
    var first15Num = str_cardNo.substr(0, str_cardNo.length - 1) // 前15或18位
    var newArr = []
    for (var i = first15Num.length - 1; i > -1; i--) { // 前15或18位倒序存进数组
      newArr.push(first15Num.substr(i, 1))
    }
    var arrJiShu = [] // 奇数位*2的积 <9
    var arrJiShu2 = [] // 奇数位*2的积 >9
    var arrOuShu = [] // 偶数位数组
    for (var j = 0; j < newArr.length; j++) {
      if ((j + 1) % 2 === 1) { // 奇数位
        if (parseInt(newArr[j]) * 2 < 9) {
          arrJiShu.push(parseInt(newArr[j]) * 2)
        } else {
          arrJiShu2.push(parseInt(newArr[j]) * 2)
        }
      } else {
        // 偶数位
        arrOuShu.push(newArr[j])
      }
    }
    var jishu_child1 = [] // 奇数位*2 >9 的分割之后的数组个位数
    var jishu_child2 = [] // 奇数位*2 >9 的分割之后的数组十位数
    for (var h = 0; h < arrJiShu2.length; h++) {
      jishu_child1.push(parseInt(arrJiShu2[h]) % 10)
      jishu_child2.push(parseInt(arrJiShu2[h]) / 10)
    }
    var sumJiShu = 0 // 奇数位*2 < 9 的数组之和
    var sumOuShu = 0 // 偶数位数组之和
    var sumJiShuChild1 = 0 // 奇数位*2 >9 的分割之后的数组个位数之和
    var sumJiShuChild2 = 0 // 奇数位*2 >9 的分割之后的数组十位数之和
    var sumTotal = 0
    for (var m = 0; m < arrJiShu.length; m++) {
      sumJiShu = sumJiShu + parseInt(arrJiShu[m])
    }
    for (var n = 0; n < arrOuShu.length; n++) {
      sumOuShu = sumOuShu + parseInt(arrOuShu[n])
    }
    for (var p = 0; p < jishu_child1.length; p++) {
      sumJiShuChild1 = sumJiShuChild1 + parseInt(jishu_child1[p])
      sumJiShuChild2 = sumJiShuChild2 + parseInt(jishu_child2[p])
    }
    // 计算总和
    sumTotal = parseInt(sumJiShu) + parseInt(sumOuShu) + parseInt(sumJiShuChild1) + parseInt(sumJiShuChild2)
    // 计算Luhm值
    var k = parseInt(sumTotal) % 10 === 0 ? 10 : parseInt(sumTotal) % 10
    var luhm = 10 - k
    if (lastNum === luhm) {
      return true
    } else {
      return false
    }
  },
  /**
	* @description 判断数据是否为IPV4地址
	* @param {String} str_data 待校验的数据
	* @returns {Boolean}, true:是IPV4地址
	**/
  isIpV4: function (str_data) {
    str_data = str_data || String(this)
    return ip4Reg.test(str_data)
  },
  /**
	* @description   判断数据是否为网址(URL),请传入满足http标准协议的链接
	* @param {String} str_data 待校验的数据
	* @param {Boolean} flag 是否使用严格模式,默认为false
	* @returns {Boolean}, true:是网址
	**/
  isUrl: function (str_data, flag) {
    str_data = str_data || String(this)
    flag = flag || false
    var regular = /^\b(((https?|ftp):\/\/)?[-a-z0-9]+(\.[-a-z0-9]+)*\.(?:com|edu|gov|int|mil|net|org|biz|info|name|museum|asia|coop|aero|[a-z][a-z]|((25[0-5])|(2[0-4]\d)|(1\d\d)|([1-9]\d)|\d))\b(\/[-a-z0-9_:\@&?=+,.!\/~%\$]*)?)$/i
    var regular2 = /^((https?|ftp):\/\/)(www\.)?\S{0,30}\.\S+$/i

    if (regular2.test(str_data) && !flag) {
      return true
    } else if (regular.test(str_data) && flag) {
      return true
    } else {
      return false
    }
  },
  validate: function (data, rules) {
    let res = { isOk: true, errmsg: '' }
    if (!rules || !rules.length) {
      return res
    }
    for (const rule of rules) {
      // rule: {name:'', type:'', errmsg:'', min:1, max:2, eq:'', required:Boolean, regex:''}
      if (!rule || !rule.name || !rule.type) {
        continue
      }

      // 如果值不存在
      if (!data[rule.name]) {
        // 如果是必填项就返回错误提示，required可以作为type是为了不同的type能给用户不同的提示
        if (rule.type === 'required' || rule.required) {
          res = { isOk: false, errmsg: rule.errmsg }
          if (!res.errmsg) {
            res.errmsg = '请正确输入所有数据' // 默认提示
          }
          return res
        }
        // 如果不是必填项就跳过
        continue
      }
      switch (rule.type) {
        // required 上面已经判断过了
        case 'equals':
        case 'eq':
          if (data[rule.name] !== data[rule.eqName]) {
            res = { isOk: false, errmsg: rule.errmsg }
          }
          break
        case 'number':
          if (!numberReg.test(data[rule.name])) {
            res = { isOk: false, errmsg: rule.errmsg }
          }
          break
        case 'int':
          if (!intReg.test(data[rule.name])) {
            res = { isOk: false, errmsg: rule.errmsg }
          }
          break
        case 'phone':
          if (!phoneReg.test(data[rule.name])) {
            res = { isOk: false, errmsg: rule.errmsg }
          }
          break
        case 'email':
          if (!emailReg.test(data[rule.name])) {
            res = { isOk: false, errmsg: rule.errmsg }
          }
          break
        case 'pwd':
          if (!pwdReg.test(data[rule.name])) {
            res = { isOk: false, errmsg: rule.errmsg }
          }
          break
        case 'inviteCode':
          if (!inviteCodeReg.test(data[rule.name])) {
            res = { isOk: false, errmsg: rule.errmsg }
          }
          break
        case 'range': // 数字类型的值取值范围
          // {name: 'xxx', type: 'range', min: 6, max: 6, required: true, errmsg: 'xxx'}
          {
            const val = data[rule.name]
            if (val) {
              if (numberReg.test(val)) {
                if (rule.min && val < rule.min) {
                  res = { isOk: false, errmsg: rule.errmsg }
                } else if (rule.max && val > rule.max) {
                  res = { isOk: false, errmsg: rule.errmsg }
                }
              } else {
                res = { isOk: false, errmsg: rule.errmsg }
              }
            }
            break
          }
        case 'lengthRange': // 字符串长度取值范围
          // {name: 'xxx', type: 'lengthRange', min: 6, max: 6, errmsg: 'xxx'}
          {
            const le = data[rule.name] ? data[rule.name].length : 0
            if (rule.min && le < rule.min) {
              res = { isOk: false, errmsg: rule.errmsg }
            } else if (rule.max && le > rule.max) {
              res = { isOk: false, errmsg: rule.errmsg }
            }
            break
          }
        case 'regex': // 自定义正则表达式
          // {name: 'xxx', type: 'regex', regex: /^1[0-9]{10,10}$/, errmsg: 'xxx'}
          if (rule.regex && !rule.regex.test(data[rule.name])) {
            res = { isOk: false, errmsg: rule.errmsg }
          }
          break
      }
      // 发现任何一个错误就立即返回，后面的不再判断
      if (!res.isOk) {
        if (!res.errmsg) {
          res.errmsg = '请正确输入所有数据' // 默认提示
        }
        return res
      }
    }
    return res
  }
}
